package eafit.sicom.mpark;

import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import android.app.Activity;
import android.util.Log;
import android.widget.Toast;
import eafit.sicom.mpark.GpsManager.PROXIMITY;
import eafit.sicom.mpark.entity.ParkingSlot;

/**
 * Manages external data and communications
 * @author Sicom
 * 
 */
public class MparkModel {
	private ParkingSlot oldParkingSlot;
	private Activity mainActivity;
	/** */
	private GpsManager gpsManager;

	/**
	 * Constructor
	 * @param mainActivity
	 */
	public MparkModel(Activity mainActivity) {
		//Log.d("*****************", "P** Init model");
		this.mainActivity = mainActivity;
		//Instancia del gps
		gpsManager = new GpsManager(mainActivity);
		//gpsManager.registerLocationListener();
		
		//Log.d("*****************", "P** Init model2");
	}

	/**
	 * Register the GPS Locator to listen
	 */
	public void registerLocationListenerGPS() {
		gpsManager.registerLocationListener();
	}

	/**
	 * Remove the GPS Listener
	 */
	public void removeUpdatesGPS() {
		gpsManager.removeUpdates();
	}
	
	/**
	 * Calculate the update time based on GPS position
	 * 
	 * @return time in miliseconds
	 */
	public int calcUpdateTime() {
		PROXIMITY proximity = gpsManager.getCurrentProximity();

		if (proximity == PROXIMITY.HIGH_HIGH) {
			return 10000;
		} else if (proximity == PROXIMITY.HIGH) {
			return 20000;
		} else if (proximity == PROXIMITY.MEDIUM) {
			return 60000;
		} else if (proximity == PROXIMITY.LOW) {
			return 120000;
		} else if (proximity == PROXIMITY.LOW_LOW) {
			return 300000;
		} else {//Will never happen
			return 20000;
		}
	}
	
	/**
	 * Gets the free parking slots from the web service
	 * 
	 * @return Slots available of the parking
	 * @throws IllegalStateException
	 * @throws IOException
	 * @throws Exception
	 */
	public ParkingSlot getFreeParkingSlots() throws IllegalStateException,
			IOException, Exception {
		
		//Recupera la informacion del Web services
		String xmlTemp = WebManager.getXmlParking();
		
		//Realiza el parse de la informacion para obtener la disponibilidad en los parqueaderos
		int[] parkingLots = parseXml(xmlTemp);
		
		ParkingSlot parkingSlot;
		
		//Verifica que traiga la informacion de los 2 parqueaderos
		if (parkingLots.length == 2) {
			parkingSlot = new ParkingSlot(parkingLots[1], parkingLots[0]);
		} 
		else {
			parkingSlot = new ParkingSlot(0, 0);
		}
		

		
		compareParkingSlots(parkingSlot);
		
		
		return parkingSlot;
	}
	
	private void compareParkingSlots(ParkingSlot parkingSlot) {
		if(oldParkingSlot==null){
			oldParkingSlot= parkingSlot;
		}
		
		//North parking slot have at least one free
		if(oldParkingSlot.getFreeNorth() < parkingSlot.getFreeNorth() && oldParkingSlot.getFreeNorth() == 0)
		{
			Toast.makeText(mainActivity, R.string.messageAvaliableNorth , Toast.LENGTH_SHORT).show();
		}
		else if(oldParkingSlot.getFreeNorth() > parkingSlot.getFreeNorth() && parkingSlot.getFreeNorth() == 0)
		{
			
			Toast.makeText(mainActivity, R.string.messageNoAvaliableNorth , Toast.LENGTH_SHORT).show();		
		}
		
		//South parking slot have at least one free
		if(oldParkingSlot.getFreeSouth() < parkingSlot.getFreeSouth() && oldParkingSlot.getFreeSouth() == 0)
		{
			
			Toast.makeText(mainActivity, R.string.messageAvaliableSouth , Toast.LENGTH_SHORT).show();		
		}
		else if(oldParkingSlot.getFreeSouth() > parkingSlot.getFreeSouth() && parkingSlot.getFreeSouth() == 0)
		{
			
			Toast.makeText(mainActivity, R.string.messageNoAvaliableSouth , Toast.LENGTH_SHORT).show();		
		}
		
		
	}

	/**
	 * Parse the xml that contains the university free parking slots
	 * 
	 * example
	 * http://www.androidpeople.com/android-xml-parsing-tutorial-%E2%80%93
	 * -using-domparser
	 * 
	 * @param xml XML with parking informaction
	 * @return Quantity of North park and South Park
	 * @throws Exception
	 */
	private int[] parseXml(String xml) throws Exception {
		//Inicializa la variable del retorno
		int parkingQuantity[] = new int[2];
		//Se carga el XML sobre el objecto Document
		DocumentBuilder builder = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder();
		Document doc = builder.parse(new InputSource(new StringReader(xml)));
		//Se le solicita la lista de tags
		NodeList parkings = doc.getElementsByTagName("parking");
		//Recorre para obtener la informacion de cada parqueadero
		for (int i = 0; i < parkings.getLength(); i++) {
			Node node = parkings.item(i);
			Element fstElmnt = (Element) node;
			
			//Solicita la cantidad de vaias disponibles
			NodeList availableQuantityList = fstElmnt
					.getElementsByTagName("availableQuantity");
			Element availableQuantityElement = (Element) availableQuantityList
					.item(0);
			availableQuantityList = availableQuantityElement.getChildNodes();
			String sAvailableQuantity = ((Node) availableQuantityList.item(0))
					.getNodeValue();

			//Recupera el nombre del parqueadero
			NodeList nameList = fstElmnt.getElementsByTagName("name");
			Element nameElement = (Element) nameList.item(0);
			nameList = nameElement.getChildNodes();
			String sName = ((Node) nameList.item(0)).getNodeValue();

			//Recupera el codigo del parqueadero
			NodeList codeList = fstElmnt.getElementsByTagName("code");
			Element codeElement = (Element) codeList.item(0);
			codeList = codeElement.getChildNodes();
			String sCode = ((Node) codeList.item(0)).getNodeValue();
			
			//Agrega la cantidad a la variable de retorno
			parkingQuantity[i] = Integer.parseInt(sAvailableQuantity);
		}
		return parkingQuantity;
	}
}